package org.ccay.vfs;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.auth.StaticUserAuthenticator;
import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
import org.ccay.core.io.FileStoreType;

/**
 * 对apache commons-vfs 进行简单封装,提供两种抽象的文件系统
 * <li>1、归档文件系统——集群部署时，各个APP可共同访问，并将生成的文件需要永久保存的文件系统 可以是本地文件系统,也可以是ftp sftp
 * hdfs等</li>
 * <li>2、工作文件系统——本APP可以访问，通常作为各个模块文件处理时的临时交换文件系统，临时文件系统的内容可能会被删除，通常是本地文件系统</li>
 * 
 * @author chaowangbang
 * @since 2.0
 */
public class VFS {

	/**
	 * 临时文件 注册项名称
	 */
	public final static String TEMP_DIR_REGISTRY_NAME = "App.TempDir";
	/**
	 * 持有FileSystemManager的实例
	 */
	private static FileSystemManager manager;

	/**
	 * 本地文件scheme
	 */
	public static String LOCAL_FILE_SCHEME = "file";
	
	/**
	 * 本地URL文件表示的前缀
	 */
	public static String LOCAL_URL_PREFIX = "file://";
	
	/**
	 * 临时文件scheme
	 */
	public static String TEMP_FILE_SCHEME = "tmp";
	
	/**
	 * 本地URL文件表示的前缀
	 */
	public static String TEMP_URL_PREFIX = "tmp:";
	
	/**
	 * 模块文件系统注册项
	 */
	private static ModuleFileSystemRegistry registry;

	public static void setRegistry(ModuleFileSystemRegistry registry) {
		VFS.registry = registry;
	}


	/**
	 * 设置FileSystemManager
	 * 
	 * @param manager
	 */
	public static void setManager(FileSystemManager manager) {
		VFS.manager = manager;
	}

	/**
	 * @param module
	 * @param relativePath
	 * @return
	 * @throws FileSystemException
	 */
	public static FileObject resolveWorkFile(String module, String relativePath){
		return resolveFile(module,FileStoreType.WROK,relativePath,null,null);
	}
	
	/**
	 * @param module
	 * @param relativePath
	 * @return
	 */
	public static FileObject resolveTempFile(String module, String relativePath) {
		return resolveFile(module,FileStoreType.TEMP,relativePath,null,null);
	}

	/**
	 * @param module
	 * @param relativePath
	 * @return
	 * @throws FileSystemException
	 */
	public static FileObject resolveArchiveFile(String module, String relativePath){
		return resolveFile(module,FileStoreType.ARCHIVE,relativePath,null,null);
	}

	public static FileObject resolveFile(String name){
		try {
			return manager.resolveFile(name);
		} catch (FileSystemException e) {
			throw new VFSException(e.getCode(),e.getMessage(),e);
		}
	}
	
	public static FileObject resolveFile(String name, String module){
		try {
			return manager.resolveFile(name,registry.getFileSystemOptions(module));
		} catch (FileSystemException e) {
			throw new VFSException(e.getCode(),e.getMessage(),e);
		}
	}
	
	public static FileObject resolveFile(String name, FileSystemOptions fileSystemOptions){
		try {
			return manager.resolveFile(name,fileSystemOptions);
		} catch (FileSystemException e) {
			throw new VFSException(e.getCode(),e.getMessage(),e);
		}
	}
	
	public static FileObject resolveFile(String module, FileStoreType sotreType,String relativePath,String compressPath,String compressScheme){
		String rootUrl = "";
		switch (sotreType) {
		case TEMP:
			rootUrl = getTempRootURI(module);
			break;
		case WROK:
			rootUrl = getWorkRootURI(module);
			break;
		case ARCHIVE:
			rootUrl = getArchiveRootURI(module);
			break;
		}
		try {
			return manager.resolveFile(
					(compressScheme == null ? "" : (compressScheme + ":")) +
					rootUrl + "/" + relativePath +
					(compressPath == null ? "" : ("!/" + compressPath)),
					registry.getFileSystemOptions(module));
		} catch (FileSystemException e) {
			throw new VFSException(e.getCode(),e.getMessage(),e);
		}
	}
	/**
	 * 获取 工作目录的 根路径
	 * @param module
	 * @return
	 */
	public static String getWorkRootURI(String module){
		return LOCAL_URL_PREFIX + registry.getWorkRoot(module);
	}
	
	/**
	 * 获取 归档陌路的 根路径
	 * @param module
	 * @return
	 */
	public static String getArchiveRootURI(String module){
		return registry.getScheme(module) + "://" + registry.getArchiveRoot(module);
	}
	
	
	public static String getTempRootURI(String module){
		return TEMP_URL_PREFIX + registry.getTempRoot(module);
	}

}
